#ifndef _imageFuncs_h_
#define _imageFuncs_h_

// imageFuncs.h
//
// non-member image functions


#include "image/imageTmpl.h"
#include "image/imageTools.h"
#include "image/imageTypes.h"

namespace simple{
  
    //
    // Mixed argument functions
    //

    //
    // add (S1, D1)
    // += (D1, S1)
    //

    template<class R, class T1, class T2, class S1, class S2>
    void accumulate (const R&, const Image<T1,S1>& src1, Image<T2,S2>& dst1)
    {
        typename Image<T1,S1>::row_iterator i1;
        typename Image<T2,S2>::row_iterator i2;
        long w = src1.width ();
        const T1* p1;
        T2* p2;
        for (i1=src1.row_begin(), i2=dst1.row_begin(); i1 != src1.row_end(); i1++, i2++) {
            p1 = i1->p;
            p2 = i2->p;
            for (int x=0; x<w; x++)
                *p2++ += *p1++;
        }
    }

    template<class T1, class S1, class T2, class S2>
    void add (const Image<T1,S1>& src, Image<T2,S2>& dst)
    {
        apFunction_s1d1<T2,T1,T2,S1,S2> processor (accumulate);
        processor.run (src, dst);
    }


    template<class T1, class S1, class T2, class S2>
    Image<T1,S1>& operator+= (Image<T1,S1>& src1, 
                                   const Image<T2,S2>& src2)
    {
        add (src2, src1);
        return src1;
    }

    //
    // subtract (S1, D1)
    // -= (D1, S1)
    //

    template<class R, class T1, class T2, class S1, class S2>
    void decumulate (const R&, const Image<T1,S1>& src1, Image<T2,S2>& dst1)
    {
        typename Image<T1,S1>::row_iterator i1;
        typename Image<T2,S2>::row_iterator i2;
        long w = src1.width ();
        const T1* p1;
        T2* p2;
        for (i1=src1.row_begin(), i2=dst1.row_begin();
            i1 != src1.row_end(); i1++, i2++) {
            p1 = i1->p;
            p2 = i2->p;
            for (int x=0; x<w; x++)
                *p2++ -= *p1++;
        }
    }

    template<class T1, class S1, class T2, class S2>
    void sub (const Image<T1,S1>& src, Image<T2,S2>& dst)
    {
        apFunction_s1d1<T2,T1,T2,S1,S2> processor (decumulate);
        processor.run (src, dst);
    }


    template<class T1, class S1, class T2, class S2>
    Image<T1,S1>& operator-= (Image<T1,S1>& src1, 
                              const Image<T2,S2>& src2)
    {
        sub (src2, src1);
        return src1;
    }

}

#endif // _imageFuncs_h_
